package freespiritsocial.io.user.viewmodel

import android.util.Log
import freespiritsocial.io.user.BuildConfig
import freespiritsocial.io.user.chat.ConnectionManager
import freespiritsocial.io.user.data.model.UploadPostEvent
import freespiritsocial.io.user.data.model.UploadPostEvent.Companion.PublishCompete
import freespiritsocial.io.user.data.model.UploadPostEvent.Companion.PublishFailed
import freespiritsocial.io.user.data.model.bean.NotificationSettingPojo
import freespiritsocial.io.user.data.model.bean.PostPojo
import freespiritsocial.io.user.data.model.bean.UpdateBean
import freespiritsocial.io.user.fcm.MyFirebaseMessagingService
import freespiritsocial.io.user.network.apiService
import freespiritsocial.io.user.network.upload.IUploadApi
import freespiritsocial.io.user.network.upload.UploadDelegate
import freespiritsocial.io.user.util.CacheUtil
import kotlinx.coroutines.Job
import me.hgj.jetpackmvvm.base.viewmodel.BaseViewModel
import me.hgj.jetpackmvvm.ext.request
import me.hgj.jetpackmvvm.ext.requestNoCheck
import me.hgj.jetpackmvvm.ext.util.TAG
import me.hgj.jetpackmvvm.network.Error

class MainViewModel: BaseViewModel(),IUploadApi by UploadDelegate() {
    private val uploadTaskMap = hashMapOf<UploadPostEvent,Job>()

    fun checkUpdate(action: (UpdateBean) -> Unit) {
        request({
            apiService.checkVersion(BuildConfig.VERSION_NAME)
        },{
            action.invoke(it)
        })
    }

    fun getUserInfo(action: (Boolean) -> Unit) {
        request({
            apiService.getUserInfo()
        },{
            CacheUtil.refreshUserInfo(it)
            ConnectionManager.login(it.resourceId) { user,error ->
                action(error == null)
            }
        })
    }

    fun getFirebase(callback: () -> Unit) {
        MyFirebaseMessagingService.getPushToken { pushToken,e ->
            request({
                Log.w(TAG,"Fetching FCM $pushToken")
                apiService.firebase(hashMapOf("firebase" to pushToken))
            },{
                callback.invoke()
            },{
                callback.invoke()
            })
        }
    }

    fun cancelUpload(event: UploadPostEvent) {
        CacheUtil.removeUploadEvent(event)
        uploadTaskMap.remove(event)?.let {
            if (it.isActive) {
                it.cancel()
            }
        }
    }

    fun getNotificationSetting() {
        request({
            apiService.getNotificationSetting()
        },{
            val pojo = it ?: NotificationSettingPojo()
            CacheUtil.setNotificationSetting(pojo)
        })
    }

    fun uploadFiles(event: UploadPostEvent,action: (UploadPostEvent) -> Unit) {
        val files = event.postPojo.uploadFiles ?: return
        val job = requestNoCheck({
            if (files.size == 1)
                listOf(uploadFile(files.first(),event))
            else
                multipartFiles(files,event)
        },{ list ->
            if (list?.isNotEmpty() == true) {
                event.postPojo.coverUrl = list.first()?.cover ?: list.first()?.url
                event.postPojo.fileUrl = list.joinToString(",") {
                    it?.url ?: ""
                }
                files.filter { it.isFile.not() && it.toString().isNotEmpty() }.let { list ->
                    event.postPojo.fileUrl += "," + list.joinToString(",") { it.toString() }
                }
            }
            event.postPojo.fileUrl = event.postPojo.fileUrl?.removeSuffix(",")
            event.status = PublishCompete
            CacheUtil.removeUploadEvent(event)
            action(event)
            uploadTaskMap.remove(event)
        },{
            if (it.errCode == Error.CANCEL.getKey()) return@requestNoCheck
            event.status = PublishFailed
            action(event)
            uploadTaskMap.remove(event)
        })
        uploadTaskMap[event] = job
    }

    fun getPost(id: Long?,action: (PostPojo) -> Unit) {
        request({
            apiService.getInvitationDetail(id)
        },{
        },isShowDialog = true)
    }
}